/**
 * Copyright 2014-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.webank.webase.front.contractStore.constant;


public class PointsConstantContext {
    public static final String BAC001_SOURCE = "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgppbXBvcnQgIi4vU2FmZU1hdGguc29sIjsKaW1wb3J0ICIuL1JvbGVzLnNvbCI7CmltcG9ydCAiLi9BZGRyZXNzLnNvbCI7Cgpjb250cmFjdCBJc3N1ZXJSb2xlIHsKICAgIHVzaW5nIFJvbGVzIGZvciBSb2xlcy5Sb2xlOwoKICAgIGV2ZW50IElzc3VlckFkZGVkKGFkZHJlc3MgaW5kZXhlZCBhY2NvdW50KTsKICAgIGV2ZW50IElzc3VlclJlbW92ZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwoKICAgIFJvbGVzLlJvbGUgcHJpdmF0ZSBfaXNzdWVyczsKCiAgICBjb25zdHJ1Y3RvciAoKSBpbnRlcm5hbCB7CiAgICAgICAgX2FkZElzc3Vlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBtb2RpZmllciBvbmx5SXNzdWVyKCkgewogICAgICAgIHJlcXVpcmUoaXNJc3N1ZXIobXNnLnNlbmRlciksICJJc3N1ZXJSb2xlOiBjYWxsZXIgZG9lcyBub3QgaGF2ZSB0aGUgSXNzdWVyIHJvbGUiKTsKICAgICAgICBfOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfaXNzdWVycy5oYXMoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIG9ubHlJc3N1ZXIgewogICAgICAgIF9hZGRJc3N1ZXIoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gcmVub3VuY2VJc3N1ZXIoKSBwdWJsaWMgewogICAgICAgIF9yZW1vdmVJc3N1ZXIobXNnLnNlbmRlcik7CiAgICB9CgogICAgZnVuY3Rpb24gX2FkZElzc3VlcihhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICBfaXNzdWVycy5hZGQoYWNjb3VudCk7CiAgICAgICAgZW1pdCBJc3N1ZXJBZGRlZChhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBfcmVtb3ZlSXNzdWVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9pc3N1ZXJzLnJlbW92ZShhY2NvdW50KTsKICAgICAgICBlbWl0IElzc3VlclJlbW92ZWQoYWNjb3VudCk7CiAgICB9Cn0KCmNvbnRyYWN0IFN1c3BlbmRlclJvbGUgewogICAgdXNpbmcgUm9sZXMgZm9yIFJvbGVzLlJvbGU7CgogICAgZXZlbnQgU3VzcGVuZGVyQWRkZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwogICAgZXZlbnQgU3VzcGVuZGVyUmVtb3ZlZChhZGRyZXNzIGluZGV4ZWQgYWNjb3VudCk7CgogICAgUm9sZXMuUm9sZSBwcml2YXRlIF9zdXNwZW5kZXJzOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfYWRkU3VzcGVuZGVyKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIG1vZGlmaWVyIG9ubHlTdXNwZW5kZXIoKSB7CiAgICAgICAgcmVxdWlyZShpc1N1c3BlbmRlcihtc2cuc2VuZGVyKSwgIlN1c3BlbmRlclJvbGU6IGNhbGxlciBkb2VzIG5vdCBoYXZlIHRoZSBTdXNwZW5kZXIgcm9sZSIpOwogICAgICAgIF87CiAgICB9CgogICAgZnVuY3Rpb24gaXNTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZXJzLmhhcyhhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBhZGRTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBwdWJsaWMgb25seVN1c3BlbmRlciB7CiAgICAgICAgX2FkZFN1c3BlbmRlcihhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiByZW5vdW5jZVN1c3BlbmRlcigpIHB1YmxpYyB7CiAgICAgICAgX3JlbW92ZVN1c3BlbmRlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBmdW5jdGlvbiBfYWRkU3VzcGVuZGVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9zdXNwZW5kZXJzLmFkZChhY2NvdW50KTsKICAgICAgICBlbWl0IFN1c3BlbmRlckFkZGVkKGFjY291bnQpOwogICAgfQoKICAgIGZ1bmN0aW9uIF9yZW1vdmVTdXNwZW5kZXIoYWRkcmVzcyBhY2NvdW50KSBpbnRlcm5hbCB7CiAgICAgICAgX3N1c3BlbmRlcnMucmVtb3ZlKGFjY291bnQpOwogICAgICAgIGVtaXQgU3VzcGVuZGVyUmVtb3ZlZChhY2NvdW50KTsKICAgIH0KfQoKY29udHJhY3QgU3VzcGVuZGFibGUgaXMgU3VzcGVuZGVyUm9sZSB7CgogICAgZXZlbnQgU3VzcGVuZGVkKGFkZHJlc3MgYWNjb3VudCk7CiAgICBldmVudCBVblN1c3BlbmRlZChhZGRyZXNzIGFjY291bnQpOwoKICAgIGJvb2wgcHJpdmF0ZSBfc3VzcGVuZGVkOwoKICAgIGNvbnN0cnVjdG9yICgpIGludGVybmFsIHsKICAgICAgICBfc3VzcGVuZGVkID0gZmFsc2U7CiAgICB9CgogICAgLyoqCiAgICAgKiBAcmV0dXJuIFRydWUgaWYgdGhlIGNvbnRyYWN0IGlzIHN1c3BlbmRlZCwgZmFsc2Ugb3RoZXJ3aXNlLgogICAgICovCiAgICBmdW5jdGlvbiBzdXNwZW5kZWQoKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKSB7CiAgICAgICAgcmV0dXJuIF9zdXNwZW5kZWQ7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IE1vZGlmaWVyIHRvIG1ha2UgYSBmdW5jdGlvbiBjYWxsYWJsZSBvbmx5IHdoZW4gdGhlIGNvbnRyYWN0IGlzIG5vdCBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5Ob3RTdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZSghX3N1c3BlbmRlZCwgIlN1c3BlbmRhYmxlOiBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBNb2RpZmllciB0byBtYWtlIGEgZnVuY3Rpb24gY2FsbGFibGUgb25seSB3aGVuIHRoZSBjb250cmFjdCBpcyBzdXNwZW5kZWQuCiAgICAgKi8KICAgIG1vZGlmaWVyIHdoZW5TdXNwZW5kZWQoKSB7CiAgICAgICAgcmVxdWlyZShfc3VzcGVuZGVkLCAiU3VzcGVuZGFibGU6IG5vdCBzdXNwZW5kZWQiKTsKICAgICAgICBfOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gc3VzcGVuZCwgdHJpZ2dlcnMgc3RvcHBlZCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gc3VzcGVuZCgpIHB1YmxpYyBvbmx5U3VzcGVuZGVyIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zdXNwZW5kZWQgPSB0cnVlOwogICAgICAgIGVtaXQgU3VzcGVuZGVkKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBDYWxsZWQgYnkgYSBTdXNwZW5kZXIgdG8gdW5TdXNwZW5kLCByZXR1cm5zIHRvIG5vcm1hbCBzdGF0ZS4KICAgICAqLwogICAgZnVuY3Rpb24gdW5TdXNwZW5kKCkgcHVibGljIG9ubHlTdXNwZW5kZXIgd2hlblN1c3BlbmRlZCB7CiAgICAgICAgX3N1c3BlbmRlZCA9IGZhbHNlOwogICAgICAgIGVtaXQgVW5TdXNwZW5kZWQobXNnLnNlbmRlcik7CiAgICB9Cn0KCmNvbnRyYWN0IElCQUMwMDFSZWNlaXZlciB7CiAgICAvKioKICAgICAqIEBub3RpY2UgSGFuZGxlIHRoZSByZWNlaXB0IG9mIGFuIE5GVAogICAgICogQGRldiBUaGUgQkFDMDAxIHNtYXJ0IGNvbnRyYWN0IGNhbGxzIHRoaXMgZnVuY3Rpb24gb24gdGhlIHJlY2lwaWVudAogICAgICovCiAgICBmdW5jdGlvbiBvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3Mgb3BlcmF0b3IsIGFkZHJlc3MgZnJvbSwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkKICAgIHB1YmxpYyByZXR1cm5zIChieXRlczQpOwp9Cgpjb250cmFjdCBCQUMwMDFIb2xkZXIgaXMgSUJBQzAwMVJlY2VpdmVyIHsKICAgIGZ1bmN0aW9uIG9uQkFDMDAxUmVjZWl2ZWQoYWRkcmVzcywgYWRkcmVzcywgdWludDI1NiwgYnl0ZXMpIHB1YmxpYyByZXR1cm5zIChieXRlczQpIHsKICAgICAgICByZXR1cm4gdGhpcy5vbkJBQzAwMVJlY2VpdmVkLnNlbGVjdG9yOwogICAgfQp9CgoKLyoqCiAqIEB0aXRsZSBTdGFuZGFyZCBCQUMwMDEgYXNzZXQKICovCmNvbnRyYWN0IEJBQzAwMSBpcyBJc3N1ZXJSb2xlLCBTdXNwZW5kYWJsZSB7CiAgICB1c2luZyBTYWZlTWF0aCBmb3IgdWludDI1NjsKICAgIHVzaW5nIEFkZHJlc3MgZm9yIGFkZHJlc3M7CgogICAgbWFwcGluZyhhZGRyZXNzID0+IHVpbnQyNTYpIHByaXZhdGUgX2JhbGFuY2VzOwogICAgbWFwcGluZyhhZGRyZXNzID0+IG1hcHBpbmcoYWRkcmVzcyA9PiB1aW50MjU2KSkgcHJpdmF0ZSBfYWxsb3dlZDsKICAgIHVpbnQyNTYgcHJpdmF0ZSBfdG90YWxBbW91bnQ7CiAgICBzdHJpbmcgcHJpdmF0ZSBfZGVzY3JpcHRpb247CiAgICBzdHJpbmcgcHJpdmF0ZSBfc2hvcnROYW1lOwogICAgdWludDggcHJpdmF0ZSAgX21pblVuaXQ7CgogICAgLy8gRXF1YWxzIHRvIGBieXRlczQoa2VjY2FrMjU2KCJvbkJBQzAwMVJlY2VpdmVkKGFkZHJlc3MsYWRkcmVzcyx1aW50MjU2LGJ5dGVzKSIpKWAKICAgIGJ5dGVzNCBwcml2YXRlIGNvbnN0YW50IF9CQUMwMDFfUkVDRUlWRUQgPSAweGM3M2QxNmFlOwoKCiAgICBldmVudCBTZW5kKCBhZGRyZXNzIGluZGV4ZWQgZnJvbSwgYWRkcmVzcyBpbmRleGVkIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKTsKICAgIGV2ZW50IEFwcHJvdmFsKCBhZGRyZXNzIGluZGV4ZWQgb3duZXIsIGFkZHJlc3MgaW5kZXhlZCBzcGVuZGVyLCB1aW50MjU2IHZhbHVlKTsKCgogICAgY29uc3RydWN0b3Ioc3RyaW5nIG1lbW9yeSBkZXNjcmlwdGlvbiwgc3RyaW5nIG1lbW9yeSBzaG9ydE5hbWUsIHVpbnQ4IG1pblVuaXQsIHVpbnQyNTYgdG90YWxBbW91bnQpIHB1YmxpYyB7CiAgICAgICAgX2Rlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICAgICAgX3Nob3J0TmFtZSA9IHNob3J0TmFtZTsKICAgICAgICBfbWluVW5pdCA9IG1pblVuaXQ7CiAgICAgICAgX2lzc3VlKG1zZy5zZW5kZXIsIHRvdGFsQW1vdW50ICogKDEwICoqIHVpbnQyNTYobWluVW5pdCkpLCAiIik7CiAgICB9CgoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHJldHVybiBfdG90YWxBbW91bnQ7CiAgICB9CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmV0dXJuIF9iYWxhbmNlc1tvd25lcl07CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEZ1bmN0aW9uIHRvIGNoZWNrIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGFsbG93YW5jZShhZGRyZXNzIG93bmVyLCBhZGRyZXNzIHNwZW5kZXIpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXR1cm4gX2FsbG93ZWRbb3duZXJdW3NwZW5kZXJdOwogICAgfQoKICAgIGZ1bmN0aW9uIHNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgICAgIF9zZW5kKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7CgogICAgfQoKLy8gICAgZnVuY3Rpb24gc2FmZVNlbmQoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewovLyAgICAgICAgc2VuZCh0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKG1zZy5zZW5kZXIsIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgLyoqCiAgICAgKiBAZGV2IEFwcHJvdmUgdGhlIHBhc3NlZCBhZGRyZXNzIHRvIHNwZW5kIHRoZSBzcGVjaWZpZWQgYW1vdW50IG9mIGFzc2V0cyBvbiBiZWhhbGYgb2YgbXNnLnNlbmRlci4KICAgICAqLwogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpIHB1YmxpYyB3aGVuTm90U3VzcGVuZGVkIHJldHVybnMgKGJvb2wpIHsKICAgICAgICBfYXBwcm92ZShtc2cuc2VuZGVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFNlbmQgYXNzZXRzIGZyb20gb25lIGFkZHJlc3MgdG8gYW5vdGhlci4KICAgICAqLwogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7CiAgICAgICAgX3NlbmQoZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgICAgICBfYXBwcm92ZShmcm9tLCBtc2cuc2VuZGVyLCBfYWxsb3dlZFtmcm9tXVttc2cuc2VuZGVyXS5zdWIodmFsdWUpKTsKICAgICAgICAvL2FkZAogICAgICAgIHJlcXVpcmUoX2NoZWNrT25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpLCAiQkFDMDAxOiBzZW5kIHRvIG5vbiBCQUMwMDFSZWNlaXZlciBpbXBsZW1lbnRlciIpOwoKCiAgICB9CgovLy8vIHNhZmUgdG9kbwovLyAgICBmdW5jdGlvbiBzYWZlU2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7Ci8vICAgICAgICBzZW5kRnJvbShmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwovLyAgICAgICAgcmVxdWlyZShfY2hlY2tPbkJBQzAwMVJlY2VpdmVkKGZyb20sIHRvLCB2YWx1ZSwgZGF0YSksICJCQUMwMDE6IHNlbmQgdG8gbm9uIEJBQzAwMVJlY2VpdmVyIGltcGxlbWVudGVyIik7Ci8vICAgIH0KCgogICAgZnVuY3Rpb24gYmF0Y2hTZW5kKGFkZHJlc3NbXSB0bywgdWludDI1NltdIHZhbHVlcywgYnl0ZXMgZGF0YSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewoKICAgICAgICAvLyBNVVNUIFRocm93IG9uIGVycm9ycwoKICAgICAgICByZXF1aXJlKHRvLmxlbmd0aCA9PSB2YWx1ZXMubGVuZ3RoLCAidG8gYW5kIHZhbHVlcyBhcnJheSBsZW5naHQgbXVzdCBtYXRjaC4iKTsKCiAgICAgICAgZm9yICh1aW50MjU2IGkgPSAwOyBpIDwgdG8ubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgcmVxdWlyZSh0b1tpXSAhPSBhZGRyZXNzKDB4MCksICJkZXN0aW5hdGlvbiBhZGRyZXNzIG11c3QgYmUgbm9uLXplcm8uIik7CgogICAgICAgICAgICBzZW5kKHRvW2ldLCB2YWx1ZXNbaV0sIGRhdGEpOwogICAgICAgIH0KICAgIH0KCgogICAgZnVuY3Rpb24gX2NoZWNrT25CQUMwMDFSZWNlaXZlZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpCiAgICBpbnRlcm5hbCByZXR1cm5zIChib29sKQogICAgewogICAgICAgIGlmICghdG8uaXNDb250cmFjdCgpKSB7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KCiAgICAgICAgYnl0ZXM0IHJldHZhbCA9IElCQUMwMDFSZWNlaXZlcih0bykub25CQUMwMDFSZWNlaXZlZChmcm9tLCB0bywgdmFsdWUsIGRhdGEpOwogICAgICAgIHJldHVybiAocmV0dmFsID09IF9CQUMwMDFfUkVDRUlWRUQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBJbmNyZWFzZSB0aGUgYW1vdW50IG9mIGFzc2V0cyB0aGF0IGFuIG93bmVyIGFsbG93ZWQgdG8gYSBzcGVuZGVyLgogICAgICovCiAgICBmdW5jdGlvbiBpbmNyZWFzZUFsbG93YW5jZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYWRkZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLmFkZChhZGRlZFZhbHVlKSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IERlY3JlYXNlIHRoZSBhbW91bnQgb2YgYXNzZXRzIHRoYXQgYW4gb3duZXIgYWxsb3dlZCB0byBhIHNwZW5kZXIuCiAgICAgKiBhcHByb3ZlIHNob3VsZCBiZSBjYWxsZWQgd2hlbiBfYWxsb3dlZFttc2cuc2VuZGVyXVtzcGVuZGVyXSA9PSAwLiBUbyBkZWNyZW1lbnQKICAgICAqLwogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgcmV0dXJucyAoYm9vbCkgewogICAgICAgIF9hcHByb3ZlKG1zZy5zZW5kZXIsIHNwZW5kZXIsIF9hbGxvd2VkW21zZy5zZW5kZXJdW3NwZW5kZXJdLnN1YihzdWJ0cmFjdGVkVmFsdWUpKTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KCiAgICBmdW5jdGlvbiBkZXN0cm95KHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3kobXNnLnNlbmRlciwgdmFsdWUsIGRhdGEpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBCdXJucyBhIHNwZWNpZmljIGFtb3VudCBvZiBhc3NldHMgZnJvbSB0aGUgdGFyZ2V0IGFkZHJlc3MgYW5kIGRlY3JlbWVudHMgYWxsb3dhbmNlLgogICAgICovCiAgICBmdW5jdGlvbiBkZXN0cm95RnJvbShhZGRyZXNzIGZyb20sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyB7CiAgICAgICAgX2Rlc3Ryb3lGcm9tKGZyb20sIHZhbHVlLCBkYXRhKTsKICAgIH0KCgogICAgZnVuY3Rpb24gZGVzY3JpcHRpb24oKSBwdWJsaWMgdmlldyByZXR1cm5zIChzdHJpbmcgbWVtb3J5KSB7CiAgICAgICAgcmV0dXJuIF9kZXNjcmlwdGlvbjsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIHNob3J0TmFtZSBvZiB0aGUgYXNzZXQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHNob3J0TmFtZSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gX3Nob3J0TmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBtaW5Vbml0IG9mIHRoZSBhc3NldC4KICAgICAqLwogICAgZnVuY3Rpb24gbWluVW5pdCgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQ4KSB7CiAgICAgICAgcmV0dXJuIF9taW5Vbml0OwogICAgfQoKCiAgICBmdW5jdGlvbiBpc3N1ZShhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWMgb25seUlzc3VlciByZXR1cm5zIChib29sKSB7CiAgICAgICAgX2lzc3VlKHRvLCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgICAvKioKICAgICAqIEBkZXYgU2VuZCBhc3NldCBmb3IgYSBzcGVjaWZpZWQgYWRkcmVzc2VzLgogICAgICovCiAgICBmdW5jdGlvbiBfc2VuZChhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKHRvICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IHNlbmQgdG8gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfYmFsYW5jZXNbZnJvbV0gPSBfYmFsYW5jZXNbZnJvbV0uc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbdG9dID0gX2JhbGFuY2VzW3RvXS5hZGQodmFsdWUpOwogICAgICAgIGVtaXQgU2VuZCggZnJvbSwgdG8sIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgSW50ZXJuYWwgZnVuY3Rpb24gdGhhdCBpc3N1ZXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBhbmQgYXNzaWducyBpdCB0bwogICAgICovCiAgICBmdW5jdGlvbiBfaXNzdWUoYWRkcmVzcyBhY2NvdW50LCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBpbnRlcm5hbCB7CiAgICAgICAgcmVxdWlyZShhY2NvdW50ICE9IGFkZHJlc3MoMCksICJCQUMwMDE6IGlzc3VlIHRvIHRoZSB6ZXJvIGFkZHJlc3MiKTsKCiAgICAgICAgX3RvdGFsQW1vdW50ID0gX3RvdGFsQW1vdW50LmFkZCh2YWx1ZSk7CiAgICAgICAgX2JhbGFuY2VzW2FjY291bnRdID0gX2JhbGFuY2VzW2FjY291bnRdLmFkZCh2YWx1ZSk7CiAgICAgICAgZW1pdCBTZW5kKCBhZGRyZXNzKDApLCBhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95KGFkZHJlc3MgYWNjb3VudCwgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUoYWNjb3VudCAhPSBhZGRyZXNzKDApLCAiQkFDMDAxOiBkZXN0cm95IGZyb20gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfdG90YWxBbW91bnQgPSBfdG90YWxBbW91bnQuc3ViKHZhbHVlKTsKICAgICAgICBfYmFsYW5jZXNbYWNjb3VudF0gPSBfYmFsYW5jZXNbYWNjb3VudF0uc3ViKHZhbHVlKTsKICAgICAgICBlbWl0IFNlbmQoIGFjY291bnQsIGFkZHJlc3MoMCksIHZhbHVlLCBkYXRhKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQXBwcm92ZSBhbiBhZGRyZXNzIHRvIHNwZW5kIGFub3RoZXIgYWRkcmVzc2VzJyBhc3NldHMuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9hcHByb3ZlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlciwgdWludDI1NiB2YWx1ZSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUob3duZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSBmcm9tIHRoZSB6ZXJvIGFkZHJlc3MiKTsKICAgICAgICByZXF1aXJlKHNwZW5kZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMTogYXBwcm92ZSB0byB0aGUgemVybyBhZGRyZXNzIik7CgogICAgICAgIF9hbGxvd2VkW293bmVyXVtzcGVuZGVyXSA9IHZhbHVlOwogICAgICAgIGVtaXQgQXBwcm92YWwoIG93bmVyLCBzcGVuZGVyLCB2YWx1ZSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRoYXQgZGVzdHJveXMgYW4gYW1vdW50IG9mIHRoZSBhc3NldCBvZiBhIGdpdmVuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9kZXN0cm95RnJvbShhZGRyZXNzIGFjY291bnQsIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICBfZGVzdHJveShhY2NvdW50LCB2YWx1ZSwgZGF0YSk7CiAgICAgICAgX2FwcHJvdmUoYWNjb3VudCwgbXNnLnNlbmRlciwgX2FsbG93ZWRbYWNjb3VudF1bbXNnLnNlbmRlcl0uc3ViKHZhbHVlKSk7CiAgICB9Cn0KCg==";
    public static final String I_BAC001_SOURCE = "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjQ7CgoKaW50ZXJmYWNlIElCQUMwMDEgewoKICAgIGZ1bmN0aW9uIHRvdGFsQW1vdW50KCkgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYmFsYW5jZShhZGRyZXNzIG93bmVyKSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KTsKCiAgICBmdW5jdGlvbiBzZW5kKGFkZHJlc3MgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpIHB1YmxpYyA7CgogICAgZnVuY3Rpb24gc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gYWxsb3dhbmNlKGFkZHJlc3Mgb3duZXIsIGFkZHJlc3Mgc3BlbmRlcikgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1Nik7CgogICAgZnVuY3Rpb24gYXBwcm92ZShhZGRyZXNzIHNwZW5kZXIsIHVpbnQyNTYgYW1vdW50KSBwdWJsaWMgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVzdHJveSh1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gZGVzdHJveUZyb20oYWRkcmVzcyBmcm9tLCB1aW50MjU2IHZhbHVlLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaXNzdWUoYWRkcmVzcyB0bywgdWludDI1NiB2YWx1ZSwgYnl0ZXMgZGF0YSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBmdW5jdGlvbiBiYXRjaFNlbmQoYWRkcmVzc1tdIHRvLCB1aW50MjU2W10gdmFsdWVzLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaW5jcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IGFkZGVkVmFsdWUpIHB1YmxpYyAgcmV0dXJucyAoYm9vbCk7CgogICAgZnVuY3Rpb24gZGVjcmVhc2VBbGxvd2FuY2UoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IHN1YnRyYWN0ZWRWYWx1ZSkgcHVibGljICByZXR1cm5zIChib29sKTsKCiAgICBldmVudCBTZW5kKGFkZHJlc3MgaW5kZXhlZCBmcm9tLCBhZGRyZXNzIGluZGV4ZWQgdG8sIHVpbnQyNTYgdmFsdWUsIGJ5dGVzIGRhdGEpOwoKICAgIGV2ZW50IEFwcHJvdmFsKGFkZHJlc3MgaW5kZXhlZCBvd25lciwgYWRkcmVzcyBpbmRleGVkIHNwZW5kZXIsIHVpbnQyNTYgdmFsdWUpOwoKfQ==";
    public static final String BAC002_SOURCE = "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7CgppbXBvcnQgIi4vUmVnaXN0ZXIuc29sIjsKaW1wb3J0ICIuL0NvdW50ZXJzLnNvbCI7CmltcG9ydCAiLi9Sb2xlcy5zb2wiOwoKCmNvbnRyYWN0IElCQUMwMDJSZWNlaXZlciB7CiAgICAvKioKICAgICAqIEBub3RpY2UgSGFuZGxlIHRoZSByZWNlaXB0IG9mIGFuIE5GVAogICAgICogQGRldiBUaGUgQkFDMDAyIHNtYXJ0IGNvbnRyYWN0IGNhbGxzIHRoaXMgZnVuY3Rpb24gb24gdGhlIHJlY2lwaWVudAogICAgICovCiAgICBmdW5jdGlvbiBvbkJBQzAwMlJlY2VpdmVkKGFkZHJlc3Mgb3BlcmF0b3IsIGFkZHJlc3MgZnJvbSwgdWludDI1NiBhc3NldElkLCBieXRlcyBtZW1vcnkgZGF0YSkKICAgIHB1YmxpYyByZXR1cm5zIChieXRlczQpOwp9Cgpjb250cmFjdCBCQUMwMDJIb2xkZXIgaXMgSUJBQzAwMlJlY2VpdmVyIHsKICAgIGZ1bmN0aW9uIG9uQkFDMDAyUmVjZWl2ZWQoYWRkcmVzcywgYWRkcmVzcywgdWludDI1NiwgYnl0ZXMgbWVtb3J5KSBwdWJsaWMgcmV0dXJucyAoYnl0ZXM0KSB7CiAgICAgICAgcmV0dXJuIHRoaXMub25CQUMwMDJSZWNlaXZlZC5zZWxlY3RvcjsKICAgIH0KfQoKY29udHJhY3QgSXNzdWVyUm9sZSB7CiAgICB1c2luZyBSb2xlcyBmb3IgUm9sZXMuUm9sZTsKCiAgICBldmVudCBJc3N1ZXJBZGRlZChhZGRyZXNzIGluZGV4ZWQgYWNjb3VudCk7CiAgICBldmVudCBJc3N1ZXJSZW1vdmVkKGFkZHJlc3MgaW5kZXhlZCBhY2NvdW50KTsKCiAgICBSb2xlcy5Sb2xlIHByaXZhdGUgX2lzc3VlcnM7CgogICAgY29uc3RydWN0b3IgKCkgaW50ZXJuYWwgewogICAgICAgIF9hZGRJc3N1ZXIobXNnLnNlbmRlcik7CiAgICB9CgogICAgbW9kaWZpZXIgb25seUlzc3VlcigpIHsKICAgICAgICByZXF1aXJlKGlzSXNzdWVyKG1zZy5zZW5kZXIpLCAiSXNzdWVyUm9sZTogY2FsbGVyIGRvZXMgbm90IGhhdmUgdGhlIElzc3VlciByb2xlIik7CiAgICAgICAgXzsKICAgIH0KCiAgICBmdW5jdGlvbiBpc0lzc3VlcihhZGRyZXNzIGFjY291bnQpIHB1YmxpYyB2aWV3IHJldHVybnMgKGJvb2wpIHsKICAgICAgICByZXR1cm4gX2lzc3VlcnMuaGFzKGFjY291bnQpOwogICAgfQoKICAgIGZ1bmN0aW9uIGFkZElzc3VlcihhZGRyZXNzIGFjY291bnQpIHB1YmxpYyBvbmx5SXNzdWVyIHsKICAgICAgICBfYWRkSXNzdWVyKGFjY291bnQpOwogICAgfQoKICAgIGZ1bmN0aW9uIHJlbm91bmNlSXNzdWVyKCkgcHVibGljIHsKICAgICAgICBfcmVtb3ZlSXNzdWVyKG1zZy5zZW5kZXIpOwogICAgfQoKICAgIGZ1bmN0aW9uIF9hZGRJc3N1ZXIoYWRkcmVzcyBhY2NvdW50KSBpbnRlcm5hbCB7CiAgICAgICAgX2lzc3VlcnMuYWRkKGFjY291bnQpOwogICAgICAgIGVtaXQgSXNzdWVyQWRkZWQoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gX3JlbW92ZUlzc3VlcihhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICBfaXNzdWVycy5yZW1vdmUoYWNjb3VudCk7CiAgICAgICAgZW1pdCBJc3N1ZXJSZW1vdmVkKGFjY291bnQpOwogICAgfQp9Cgpjb250cmFjdCBTdXNwZW5kZXJSb2xlIHsKICAgIHVzaW5nIFJvbGVzIGZvciBSb2xlcy5Sb2xlOwoKICAgIGV2ZW50IFN1c3BlbmRlckFkZGVkKGFkZHJlc3MgaW5kZXhlZCBhY2NvdW50KTsKICAgIGV2ZW50IFN1c3BlbmRlclJlbW92ZWQoYWRkcmVzcyBpbmRleGVkIGFjY291bnQpOwoKICAgIFJvbGVzLlJvbGUgcHJpdmF0ZSBfc3VzcGVuZGVyczsKCiAgICBjb25zdHJ1Y3RvciAoKSBpbnRlcm5hbCB7CiAgICAgICAgX2FkZFN1c3BlbmRlcihtc2cuc2VuZGVyKTsKICAgIH0KCiAgICBtb2RpZmllciBvbmx5U3VzcGVuZGVyKCkgewogICAgICAgIHJlcXVpcmUoaXNTdXNwZW5kZXIobXNnLnNlbmRlciksICJTdXNwZW5kZXJSb2xlOiBjYWxsZXIgZG9lcyBub3QgaGF2ZSB0aGUgU3VzcGVuZGVyIHJvbGUiKTsKICAgICAgICBfOwogICAgfQoKICAgIGZ1bmN0aW9uIGlzU3VzcGVuZGVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfc3VzcGVuZGVycy5oYXMoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gYWRkU3VzcGVuZGVyKGFkZHJlc3MgYWNjb3VudCkgcHVibGljIG9ubHlTdXNwZW5kZXIgewogICAgICAgIF9hZGRTdXNwZW5kZXIoYWNjb3VudCk7CiAgICB9CgogICAgZnVuY3Rpb24gcmVub3VuY2VTdXNwZW5kZXIoKSBwdWJsaWMgewogICAgICAgIF9yZW1vdmVTdXNwZW5kZXIobXNnLnNlbmRlcik7CiAgICB9CgogICAgZnVuY3Rpb24gX2FkZFN1c3BlbmRlcihhZGRyZXNzIGFjY291bnQpIGludGVybmFsIHsKICAgICAgICBfc3VzcGVuZGVycy5hZGQoYWNjb3VudCk7CiAgICAgICAgZW1pdCBTdXNwZW5kZXJBZGRlZChhY2NvdW50KTsKICAgIH0KCiAgICBmdW5jdGlvbiBfcmVtb3ZlU3VzcGVuZGVyKGFkZHJlc3MgYWNjb3VudCkgaW50ZXJuYWwgewogICAgICAgIF9zdXNwZW5kZXJzLnJlbW92ZShhY2NvdW50KTsKICAgICAgICBlbWl0IFN1c3BlbmRlclJlbW92ZWQoYWNjb3VudCk7CiAgICB9Cn0KCmNvbnRyYWN0IFN1c3BlbmRhYmxlIGlzIFN1c3BlbmRlclJvbGUgewoKICAgIGV2ZW50IFN1c3BlbmRlZChhZGRyZXNzIGFjY291bnQpOwogICAgZXZlbnQgVW5TdXNwZW5kZWQoYWRkcmVzcyBhY2NvdW50KTsKCiAgICBib29sIHByaXZhdGUgX3N1c3BlbmRlZDsKCiAgICBjb25zdHJ1Y3RvciAoKSBpbnRlcm5hbCB7CiAgICAgICAgX3N1c3BlbmRlZCA9IGZhbHNlOwogICAgfQoKICAgIC8qKgogICAgICogQHJldHVybiBUcnVlIGlmIHRoZSBjb250cmFjdCBpcyBzdXNwZW5kZWQsIGZhbHNlIG90aGVyd2lzZS4KICAgICAqLwogICAgZnVuY3Rpb24gc3VzcGVuZGVkKCkgcHVibGljIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfc3VzcGVuZGVkOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBNb2RpZmllciB0byBtYWtlIGEgZnVuY3Rpb24gY2FsbGFibGUgb25seSB3aGVuIHRoZSBjb250cmFjdCBpcyBub3Qgc3VzcGVuZGVkLgogICAgICovCiAgICBtb2RpZmllciB3aGVuTm90U3VzcGVuZGVkKCkgewogICAgICAgIHJlcXVpcmUoIV9zdXNwZW5kZWQsICJTdXNwZW5kYWJsZTogc3VzcGVuZGVkIik7CiAgICAgICAgXzsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgTW9kaWZpZXIgdG8gbWFrZSBhIGZ1bmN0aW9uIGNhbGxhYmxlIG9ubHkgd2hlbiB0aGUgY29udHJhY3QgaXMgc3VzcGVuZGVkLgogICAgICovCiAgICBtb2RpZmllciB3aGVuU3VzcGVuZGVkKCkgewogICAgICAgIHJlcXVpcmUoX3N1c3BlbmRlZCwgIlN1c3BlbmRhYmxlOiBub3Qgc3VzcGVuZGVkIik7CiAgICAgICAgXzsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQ2FsbGVkIGJ5IGEgU3VzcGVuZGVyIHRvIHN1c3BlbmQsIHRyaWdnZXJzIHN0b3BwZWQgc3RhdGUuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHN1c3BlbmQoKSBwdWJsaWMgb25seVN1c3BlbmRlciB3aGVuTm90U3VzcGVuZGVkIHsKICAgICAgICBfc3VzcGVuZGVkID0gdHJ1ZTsKICAgICAgICBlbWl0IFN1c3BlbmRlZChtc2cuc2VuZGVyKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQ2FsbGVkIGJ5IGEgU3VzcGVuZGVyIHRvIHVuU3VzcGVuZCwgcmV0dXJucyB0byBub3JtYWwgc3RhdGUuCiAgICAgKi8KICAgIGZ1bmN0aW9uIHVuU3VzcGVuZCgpIHB1YmxpYyBvbmx5U3VzcGVuZGVyIHdoZW5TdXNwZW5kZWQgewogICAgICAgIF9zdXNwZW5kZWQgPSBmYWxzZTsKICAgICAgICBlbWl0IFVuU3VzcGVuZGVkKG1zZy5zZW5kZXIpOwogICAgfQp9CgovL2RlbGV0ZSByZWdpc3Rlcgpjb250cmFjdCBCQUMwMDIgaXMgIElzc3VlclJvbGUsIFN1c3BlbmRhYmxlIHsKICAgIHVzaW5nIFNhZmVNYXRoIGZvciB1aW50MjU2OwogICAgdXNpbmcgQWRkcmVzcyBmb3IgYWRkcmVzczsKICAgIHVzaW5nIENvdW50ZXJzIGZvciBDb3VudGVycy5Db3VudGVyOwoKICAgIC8vIEVxdWFscyB0byBgYnl0ZXM0KGtlY2NhazI1Nigib25CQUMwMDJSZWNlaXZlZChhZGRyZXNzLGFkZHJlc3MsdWludDI1NixieXRlcykiKSlgCiAgICBieXRlczQgcHJpdmF0ZSBjb25zdGFudCBfQkFDMDAyX1JFQ0VJVkVEID0gMHgzMWY2ZjUwZTsKCiAgICAvLyBNYXBwaW5nIGZyb20gYXNzZXQgSUQgdG8gb3duZXIKICAgIG1hcHBpbmcodWludDI1NiA9PiBhZGRyZXNzKSBwcml2YXRlIF9hc3NldE93bmVyOwoKICAgIC8vIE1hcHBpbmcgZnJvbSBhc3NldCBJRCB0byBhcHByb3ZlZCBhZGRyZXNzCiAgICBtYXBwaW5nKHVpbnQyNTYgPT4gYWRkcmVzcykgcHJpdmF0ZSBfYXNzZXRBcHByb3ZhbHM7CgogICAgLy8gTWFwcGluZyBmcm9tIG93bmVyIHRvIG51bWJlciBvZiBvd25lZCBhc3NldAogICAgbWFwcGluZyhhZGRyZXNzID0+IENvdW50ZXJzLkNvdW50ZXIpIHByaXZhdGUgX293bmVkQXNzZXRzQ291bnQ7CgogICAgLy8gTWFwcGluZyBmcm9tIG93bmVyIHRvIG9wZXJhdG9yIGFwcHJvdmFscwogICAgbWFwcGluZyhhZGRyZXNzID0+IG1hcHBpbmcoYWRkcmVzcyA9PiBib29sKSkgcHJpdmF0ZSBfb3BlcmF0b3JBcHByb3ZhbHM7CgogICAgc3RyaW5nIHByaXZhdGUgX2Rlc2NyaXB0aW9uOwoKICAgIHN0cmluZyBwcml2YXRlIF9zaG9ydE5hbWU7CgogICAgLy8gT3B0aW9uYWwgbWFwcGluZyBmb3IgYXNzZXQgVVJJcwogICAgbWFwcGluZyh1aW50MjU2ID0+IHN0cmluZykgcHJpdmF0ZSBfYXNzZXRVUklzOwoKICAgIC8vIE1hcHBpbmcgZnJvbSBvd25lciB0byBsaXN0IG9mIG93bmVkIGFzc2V0IElEcwogICAgbWFwcGluZyhhZGRyZXNzID0+IHVpbnQyNTZbXSkgcHJpdmF0ZSBfb3duZWRBc3NldHM7CgogICAgLy8gTWFwcGluZyBmcm9tIGFzc2V0IElEIHRvIGluZGV4IG9mIHRoZSBvd25lciBhc3NldHMgbGlzdAogICAgbWFwcGluZyh1aW50MjU2ID0+IHVpbnQyNTYpIHByaXZhdGUgX293bmVkQXNzZXRzSW5kZXg7CgogICAgLy8gQXJyYXkgd2l0aCBhbGwgYXNzZXQgaWRzLCB1c2VkIGZvciBlbnVtZXJhdGlvbgogICAgdWludDI1NltdIHByaXZhdGUgX2FsbEFzc2V0czsKCiAgICAvLyBNYXBwaW5nIGZyb20gYXNzZXQgaWQgdG8gcG9zaXRpb24gaW4gdGhlIGFsbEFzc2V0cyBhcnJheQogICAgbWFwcGluZyh1aW50MjU2ID0+IHVpbnQyNTYpIHByaXZhdGUgX2FsbEFzc2V0c0luZGV4OwoKICAgIGV2ZW50IFNlbmQoYWRkcmVzcyBpbmRleGVkIG9wZXJhdG9yLCBhZGRyZXNzIGluZGV4ZWQgZnJvbSwgYWRkcmVzcyBpbmRleGVkIHRvLCB1aW50MjU2IGFzc2V0SWQsIGJ5dGVzIGRhdGEpOwogICAgZXZlbnQgQXBwcm92YWwoIGFkZHJlc3MgaW5kZXhlZCBvd25lciwgYWRkcmVzcyBhcHByb3ZlZCwgdWludDI1NiBhc3NldElkKTsKICAgIGV2ZW50IEFwcHJvdmFsRm9yQWxsKCBhZGRyZXNzIGluZGV4ZWQgb3duZXIsIGFkZHJlc3MgaW5kZXhlZCBvcGVyYXRvciwgYm9vbCBhcHByb3ZlZCk7CgogICAgLy8gY29uc3RydWN0b3IKICAgIGNvbnN0cnVjdG9yKHN0cmluZyBkZXNjcmlwdGlvbiwgc3RyaW5nIHNob3J0TmFtZSkgcHVibGljCiAgICB7CiAgICAgICAgX2Rlc2NyaXB0aW9uID0gZGVzY3JpcHRpb247CiAgICAgICAgX3Nob3J0TmFtZSA9IHNob3J0TmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgR2V0cyB0aGUgYmFsYW5jZSBvZiB0aGUgc3BlY2lmaWVkIGFkZHJlc3MuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGJhbGFuY2UoYWRkcmVzcyBvd25lcikgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1NikgewogICAgICAgIHJlcXVpcmUob3duZXIgIT0gYWRkcmVzcygwKSwgIkJBQzAwMjogYmFsYW5jZSBxdWVyeSBmb3IgdGhlIHplcm8gYWRkcmVzcyIpOwogICAgICAgIHJldHVybiBfb3duZWRBc3NldHNDb3VudFtvd25lcl0uY3VycmVudCgpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBHZXRzIHRoZSBvd25lciBvZiB0aGUgc3BlY2lmaWVkIGFzc2V0IElELgogICAgICovCiAgICBmdW5jdGlvbiBvd25lck9mKHVpbnQyNTYgYXNzZXRJZCkgcHVibGljIHZpZXcgcmV0dXJucyAoYWRkcmVzcykgewogICAgICAgIGFkZHJlc3Mgb3duZXIgPSBfYXNzZXRPd25lclthc3NldElkXTsKICAgICAgICByZXF1aXJlKG93bmVyICE9IGFkZHJlc3MoMCksICJCQUMwMDI6IG93bmVyIHF1ZXJ5IGZvciBub25leGlzdGVudCBhc3NldCIpOwogICAgICAgIHJldHVybiBvd25lcjsKICAgIH0KCgogICAgZnVuY3Rpb24gYXNzZXRPZk93bmVyQnlJbmRleChhZGRyZXNzIG93bmVyLCB1aW50MjU2IGluZGV4KSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShpbmRleCA8IGJhbGFuY2Uob3duZXIpLCAiQkFDMDAyRW51bWVyYWJsZTogb3duZXIgaW5kZXggb3V0IG9mIGJvdW5kcyIpOwogICAgICAgIHJldHVybiBfb3duZWRBc3NldHNbb3duZXJdW2luZGV4XTsKICAgIH0KCiAgICBmdW5jdGlvbiBhc3NldE9mT3duZXIoYWRkcmVzcyBvd25lcikgcHVibGljIHZpZXcgcmV0dXJucyAodWludDI1NltdKSB7CiAgICAgICAgcmV0dXJuIF9vd25lZEFzc2V0c1tvd25lcl07CiAgICB9CgoKICAgIGZ1bmN0aW9uIGFzc2V0QnlJbmRleCh1aW50MjU2IGluZGV4KSBwdWJsaWMgdmlldyByZXR1cm5zICh1aW50MjU2KSB7CiAgICAgICAgcmVxdWlyZShpbmRleCA8IHRvdGFsU3VwcGx5KCksICJCQUMwMDJFbnVtZXJhYmxlOiBnbG9iYWwgaW5kZXggb3V0IG9mIGJvdW5kcyIpOwogICAgICAgIHJldHVybiBfYWxsQXNzZXRzW2luZGV4XTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgQXBwcm92ZXMgYW5vdGhlciBhZGRyZXNzIHRvIHNlbmQgdGhlIGdpdmVuIGFzc2V0IElECiAgICAgKi8KICAgIGZ1bmN0aW9uIGFwcHJvdmUoYWRkcmVzcyB0bywgdWludDI1NiBhc3NldElkKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7CiAgICAgICAgYWRkcmVzcyBvd25lciA9IG93bmVyT2YoYXNzZXRJZCk7CiAgICAgICAgcmVxdWlyZSh0byAhPSBvd25lciwgIkJBQzAwMjogYXBwcm92YWwgdG8gY3VycmVudCBvd25lciIpOwoKICAgICAgICByZXF1aXJlKG1zZy5zZW5kZXIgPT0gb3duZXIgfHwgaXNBcHByb3ZlZEZvckFsbChvd25lciwgbXNnLnNlbmRlciksCiAgICAgICAgICAgICJCQUMwMDI6IGFwcHJvdmUgY2FsbGVyIGlzIG5vdCBvd25lciBub3IgYXBwcm92ZWQgZm9yIGFsbCIKICAgICAgICApOwogICAgICAgIF9hc3NldEFwcHJvdmFsc1thc3NldElkXSA9IHRvOwogICAgICAgIGVtaXQgQXBwcm92YWwoIG93bmVyLCB0bywgYXNzZXRJZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEdldHMgdGhlIGFwcHJvdmVkIGFkZHJlc3MgZm9yIGEgYXNzZXQgSUQsIG9yIHplcm8gaWYgbm8gYWRkcmVzcyBzZXQKICAgICAqLwogICAgZnVuY3Rpb24gZ2V0QXBwcm92ZWQodWludDI1NiBhc3NldElkKSBwdWJsaWMgdmlldyByZXR1cm5zIChhZGRyZXNzKSB7CiAgICAgICAgcmVxdWlyZShfZXhpc3RzKGFzc2V0SWQpLCAiQkFDMDAyOiBhcHByb3ZlZCBxdWVyeSBmb3Igbm9uZXhpc3RlbnQgYXNzZXQiKTsKICAgICAgICByZXR1cm4gX2Fzc2V0QXBwcm92YWxzW2Fzc2V0SWRdOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBTZXRzIG9yIHVuc2V0cyB0aGUgYXBwcm92YWwgb2YgYSBnaXZlbiBvcGVyYXRvcgogICAgICovCiAgICBmdW5jdGlvbiBzZXRBcHByb3ZhbEZvckFsbChhZGRyZXNzIHRvLCBib29sIGFwcHJvdmVkKSBwdWJsaWMgd2hlbk5vdFN1c3BlbmRlZCB7CiAgICAgICAgcmVxdWlyZSh0byAhPSBtc2cuc2VuZGVyLCAiQkFDMDAyOiBhcHByb3ZlIHRvIGNhbGxlciIpOwogICAgICAgIF9vcGVyYXRvckFwcHJvdmFsc1ttc2cuc2VuZGVyXVt0b10gPSBhcHByb3ZlZDsKICAgICAgICBlbWl0IEFwcHJvdmFsRm9yQWxsKCBtc2cuc2VuZGVyLCB0bywgYXBwcm92ZWQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBUZWxscyB3aGV0aGVyIGFuIG9wZXJhdG9yIGlzIGFwcHJvdmVkIGJ5IGEgZ2l2ZW4gb3duZXIuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGlzQXBwcm92ZWRGb3JBbGwoYWRkcmVzcyBvd25lciwgYWRkcmVzcyBvcGVyYXRvcikgcHVibGljIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJldHVybiBfb3BlcmF0b3JBcHByb3ZhbHNbb3duZXJdW29wZXJhdG9yXTsKICAgIH0KCi8vICAgIC8qKgovLyAgICAgKiBAZGV2IFNlbmRzIHRoZSBvd25lcnNoaXAgb2YgYSBnaXZlbiBhc3NldCBJRCB0byBhbm90aGVyIGFkZHJlc3MuCi8vICAgICAqLwovLyAgICBmdW5jdGlvbiBzZW5kRnJvbShhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgYXNzZXRJZCwgYnl0ZXMgbWVtb3J5IGRhdGEpIHB1YmxpYyB3aGVuTm90U3VzcGVuZGVkIHsKLy8gICAgICAgIC8vc29saGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGluZS1sZW5ndGgKLy8gICAgICAgIHJlcXVpcmUoX2lzQXBwcm92ZWRPck93bmVyKG1zZy5zZW5kZXIsIGFzc2V0SWQpLCAiQkFDMDAyOiBzZW5kIGNhbGxlciBpcyBub3Qgb3duZXIgbm9yIGFwcHJvdmVkIik7Ci8vICAgICAgICBfc2VuZEZyb20oZnJvbSwgdG8sIGFzc2V0SWQsIGRhdGEpOwovLyAgICB9CgogICAgLy8gLyoqCiAgICAvLyAgKiBAZGV2IFNhZmVseSBzZW5kcyB0aGUgb3duZXJzaGlwIG9mIGEgZ2l2ZW4gYXNzZXQgSUQgdG8gYW5vdGhlciBhZGRyZXNzCiAgICAvLyAgKi8KICAgIC8vIGZ1bmN0aW9uIHNhZmVTZW5kRnJvbShhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgYXNzZXRJZCkgcHVibGljIHdoZW5Ob3RTdXNwZW5kZWQgewogICAgLy8gICAgIHNhZmVTZW5kRnJvbShmcm9tLCB0bywgYXNzZXRJZCwgIiIpOwogICAgLy8gfQoKICAgIC8qKgogICAgICogQGRldiBTYWZlbHkgc2VuZHMgdGhlIG93bmVyc2hpcCBvZiBhIGdpdmVuIGFzc2V0IElEIHRvIGFub3RoZXIgYWRkcmVzcwogICAgICovCiAgICBmdW5jdGlvbiBzZW5kRnJvbShhZGRyZXNzIGZyb20sIGFkZHJlc3MgdG8sIHVpbnQyNTYgYXNzZXRJZCwgYnl0ZXMgbWVtb3J5IGRhdGEpIHB1YmxpYyB3aGVuTm90U3VzcGVuZGVkIHsKCgogICAgICAgIHJlcXVpcmUoX2lzQXBwcm92ZWRPck93bmVyKG1zZy5zZW5kZXIsIGFzc2V0SWQpLCAiQkFDMDAyOiBzZW5kIGNhbGxlciBpcyBub3Qgb3duZXIgbm9yIGFwcHJvdmVkIik7CiAgICAgICAgX3NlbmRGcm9tKGZyb20sIHRvLCBhc3NldElkLCBkYXRhKTsKICAgICAgICByZXF1aXJlKF9jaGVja09uQkFDMDAyUmVjZWl2ZWQoZnJvbSwgdG8sIGFzc2V0SWQsIGRhdGEpLCAiQkFDMDAyOiBzZW5kIHRvIG5vbiBCQUMwMDJSZWNlaXZlciBpbXBsZW1lbnRlciIpOwogICAgfQoKCiAgICBmdW5jdGlvbiBiYXRjaFNlbmRGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzc1tdIHRvLCB1aW50MjU2W10gYXNzZXRJZCwgYnl0ZXMgbWVtb3J5IGRhdGEpIHB1YmxpYyB3aGVuTm90U3VzcGVuZGVkIHsKCiAgICAgICAgcmVxdWlyZSh0by5sZW5ndGggPT0gYXNzZXRJZC5sZW5ndGgsICJ0byBhbmQgYXNzZXRJZCBhcnJheSBsZW5naHQgbXVzdCBtYXRjaC4iKTsKCiAgICAgICAgZm9yICh1aW50MjU2IGkgPSAwOyBpIDwgdG8ubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgcmVxdWlyZSh0b1tpXSAhPSBhZGRyZXNzKDB4MCksICJkZXN0aW5hdGlvbiBhZGRyZXNzIG11c3QgYmUgbm9uLXplcm8uIik7CiAgICAgICAgICAgIHNlbmRGcm9tKGZyb20sIHRvW2ldLCBhc3NldElkW2ldLCBkYXRhKTsKCiAgICAgICAgfQogICAgfQoKCiAgICBmdW5jdGlvbiBkZXN0cm95KHVpbnQyNTYgYXNzZXRJZCwgYnl0ZXMgZGF0YSkgcHVibGljIHsKICAgICAgICAvL3NvbGhpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxpbmUtbGVuZ3RoCiAgICAgICAgcmVxdWlyZShfaXNBcHByb3ZlZE9yT3duZXIobXNnLnNlbmRlciwgYXNzZXRJZCksICJCQUMwMDJCdXJuYWJsZTogY2FsbGVyIGlzIG5vdCBvd25lciBub3IgYXBwcm92ZWQiKTsKICAgICAgICBfZGVzdHJveShhc3NldElkLCBkYXRhKTsKICAgIH0KCiAgICAvL2FkZCBpc3N1ZXJBZGRyZXNzCiAgICBmdW5jdGlvbiBpc3N1ZVdpdGhBc3NldFVSSShhZGRyZXNzIHRvLCB1aW50MjU2IGFzc2V0SWQsIHN0cmluZyBtZW1vcnkgYXNzZXRVUkksIGJ5dGVzIGRhdGEpIHB1YmxpYyBvbmx5SXNzdWVyIHJldHVybnMgKGJvb2wpIHsKICAgICAgICBfaXNzdWUoIHRvLCBhc3NldElkLCBkYXRhKTsKICAgICAgICBfc2V0QXNzZXRVUkkoYXNzZXRJZCwgYXNzZXRVUkkpOwogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGZ1bmN0aW9uIGRlc2NyaXB0aW9uKCkgZXh0ZXJuYWwgdmlldyByZXR1cm5zIChzdHJpbmcgbWVtb3J5KSB7CiAgICAgICAgcmV0dXJuIF9kZXNjcmlwdGlvbjsKICAgIH0KCiAgICBmdW5jdGlvbiBzaG9ydE5hbWUoKSBleHRlcm5hbCB2aWV3IHJldHVybnMgKHN0cmluZyBtZW1vcnkpIHsKICAgICAgICByZXR1cm4gX3Nob3J0TmFtZTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgUmV0dXJucyBhbiBVUkkgZm9yIGEgZ2l2ZW4gYXNzZXQgSUQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIGFzc2V0VVJJKHVpbnQyNTYgYXNzZXRJZCkgZXh0ZXJuYWwgdmlldyByZXR1cm5zIChzdHJpbmcgbWVtb3J5KSB7CiAgICAgICAgcmVxdWlyZShfZXhpc3RzKGFzc2V0SWQpLCAiQkFDMDAyTWV0YWRhdGE6IFVSSSBxdWVyeSBmb3Igbm9uZXhpc3RlbnQgYXNzZXQiKTsKICAgICAgICByZXR1cm4gX2Fzc2V0VVJJc1thc3NldElkXTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgSW50ZXJuYWwgZnVuY3Rpb24gdG8gc2V0IHRoZSBhc3NldCBVUkkgZm9yIGEgZ2l2ZW4gYXNzZXQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9zZXRBc3NldFVSSSh1aW50MjU2IGFzc2V0SWQsIHN0cmluZyBtZW1vcnkgdXJpKSBpbnRlcm5hbCB7CiAgICAgICAgcmVxdWlyZShfZXhpc3RzKGFzc2V0SWQpLCAiQkFDMDAyTWV0YWRhdGE6IFVSSSBzZXQgb2Ygbm9uZXhpc3RlbnQgYXNzZXQiKTsKICAgICAgICBfYXNzZXRVUklzW2Fzc2V0SWRdID0gdXJpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBSZXR1cm5zIHdoZXRoZXIgdGhlIHNwZWNpZmllZCBhc3NldCBleGlzdHMuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9leGlzdHModWludDI1NiBhc3NldElkKSBpbnRlcm5hbCB2aWV3IHJldHVybnMgKGJvb2wpIHsKICAgICAgICBhZGRyZXNzIG93bmVyID0gX2Fzc2V0T3duZXJbYXNzZXRJZF07CiAgICAgICAgcmV0dXJuIG93bmVyICE9IGFkZHJlc3MoMCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFJldHVybnMgd2hldGhlciB0aGUgZ2l2ZW4gc3BlbmRlciBjYW4gc2VuZCBhIGdpdmVuIGFzc2V0IElELgogICAgICovCiAgICBmdW5jdGlvbiBfaXNBcHByb3ZlZE9yT3duZXIoYWRkcmVzcyBzcGVuZGVyLCB1aW50MjU2IGFzc2V0SWQpIGludGVybmFsIHZpZXcgcmV0dXJucyAoYm9vbCkgewogICAgICAgIHJlcXVpcmUoX2V4aXN0cyhhc3NldElkKSwgIkJBQzAwMjogb3BlcmF0b3IgcXVlcnkgZm9yIG5vbmV4aXN0ZW50IGFzc2V0Iik7CiAgICAgICAgYWRkcmVzcyBvd25lciA9IG93bmVyT2YoYXNzZXRJZCk7CiAgICAgICAgcmV0dXJuIChzcGVuZGVyID09IG93bmVyIHx8IGdldEFwcHJvdmVkKGFzc2V0SWQpID09IHNwZW5kZXIgfHwgaXNBcHByb3ZlZEZvckFsbChvd25lciwgc3BlbmRlcikpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBJbnRlcm5hbCBmdW5jdGlvbiB0byBtaW50IGEgbmV3IGFzc2V0LgogICAgICovCiAgICBmdW5jdGlvbiBfaXNzdWUoIGFkZHJlc3MgdG8sIHVpbnQyNTYgYXNzZXRJZCwgYnl0ZXMgZGF0YSkgaW50ZXJuYWwgewogICAgICAgIHJlcXVpcmUodG8gIT0gYWRkcmVzcygwKSwgIkJBQzAwMjogbWludCB0byB0aGUgemVybyBhZGRyZXNzIik7CiAgICAgICAgcmVxdWlyZSghX2V4aXN0cyhhc3NldElkKSwgIkJBQzAwMjogYXNzZXQgYWxyZWFkeSBtaW50ZWQiKTsKCiAgICAgICAgX2Fzc2V0T3duZXJbYXNzZXRJZF0gPSB0bzsKICAgICAgICBfb3duZWRBc3NldHNDb3VudFt0b10uaW5jcmVtZW50KCk7CgogICAgICAgIGVtaXQgU2VuZChtc2cuc2VuZGVyLCBhZGRyZXNzKDApLCB0bywgYXNzZXRJZCwgZGF0YSk7CgogICAgICAgIF9hZGRBc3NldFRvT3duZXJFbnVtZXJhdGlvbih0bywgYXNzZXRJZCk7CgogICAgICAgIF9hZGRBc3NldFRvQWxsQXNzZXRzRW51bWVyYXRpb24oYXNzZXRJZCk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRvIGRlc3Ryb3kgYSBzcGVjaWZpYyBhc3NldC4KICAgICAqIFJldmVydHMgaWYgdGhlIGFzc2V0IGRvZXMgbm90IGV4aXN0LgogICAgICovCiAgICBmdW5jdGlvbiBfZGVzdHJveShhZGRyZXNzIG93bmVyLCB1aW50MjU2IGFzc2V0SWQsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKG93bmVyT2YoYXNzZXRJZCkgPT0gb3duZXIsICJCQUMwMDI6IGRlc3Ryb3kgb2YgYXNzZXQgdGhhdCBpcyBub3Qgb3duIik7CgogICAgICAgIF9jbGVhckFwcHJvdmFsKGFzc2V0SWQpOwoKICAgICAgICBfb3duZWRBc3NldHNDb3VudFtvd25lcl0uZGVjcmVtZW50KCk7CiAgICAgICAgX2Fzc2V0T3duZXJbYXNzZXRJZF0gPSBhZGRyZXNzKDApOwoKICAgICAgICBpZiAoYnl0ZXMoX2Fzc2V0VVJJc1thc3NldElkXSkubGVuZ3RoICE9IDApIHsKICAgICAgICAgICAgZGVsZXRlIF9hc3NldFVSSXNbYXNzZXRJZF07CiAgICAgICAgfQoKICAgICAgICBlbWl0IFNlbmQodGhpcywgb3duZXIsIGFkZHJlc3MoMCksIGFzc2V0SWQsIGRhdGEpOwoKICAgICAgICBfcmVtb3ZlQXNzZXRGcm9tT3duZXJFbnVtZXJhdGlvbihvd25lciwgYXNzZXRJZCk7CiAgICAgICAgLy8gU2luY2UgYXNzZXRJZCB3aWxsIGJlIGRlbGV0ZWQsIHdlIGNhbiBjbGVhciBpdHMgc2xvdCBpbiBfb3duZWRBc3NldHNJbmRleCB0byB0cmlnZ2VyIGEgZ2FzIHJlZnVuZAogICAgICAgIF9vd25lZEFzc2V0c0luZGV4W2Fzc2V0SWRdID0gMDsKCiAgICAgICAgX3JlbW92ZUFzc2V0RnJvbUFsbEFzc2V0c0VudW1lcmF0aW9uKGFzc2V0SWQpOwogICAgfQoKCiAgICAvKioKICAgICAqIEBkZXYgR2V0cyB0aGUgdG90YWwgYW1vdW50IG9mIGFzc2V0cyBzdG9yZWQgYnkgdGhlIGNvbnRyYWN0LgogICAgICogQHJldHVybiB1aW50MjU2IHJlcHJlc2VudGluZyB0aGUgdG90YWwgYW1vdW50IG9mIGFzc2V0cwogICAgICovCiAgICBmdW5jdGlvbiB0b3RhbFN1cHBseSgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQyNTYpIHsKICAgICAgICByZXR1cm4gX2FsbEFzc2V0cy5sZW5ndGg7CiAgICB9CgoKICAgIGZ1bmN0aW9uIF9hc3NldHNPZk93bmVyKGFkZHJlc3Mgb3duZXIpIGludGVybmFsIHZpZXcgcmV0dXJucyAodWludDI1NltdIHN0b3JhZ2UpIHsKICAgICAgICByZXR1cm4gX293bmVkQXNzZXRzW293bmVyXTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgUHJpdmF0ZSBmdW5jdGlvbiB0byBhZGQgYSBhc3NldCB0byB0aGlzIGV4dGVuc2lvbidzIG93bmVyc2hpcC10cmFja2luZyBkYXRhIHN0cnVjdHVyZXMuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9hZGRBc3NldFRvT3duZXJFbnVtZXJhdGlvbihhZGRyZXNzIHRvLCB1aW50MjU2IGFzc2V0SWQpIHByaXZhdGUgewogICAgICAgIF9vd25lZEFzc2V0c0luZGV4W2Fzc2V0SWRdID0gX293bmVkQXNzZXRzW3RvXS5sZW5ndGg7CiAgICAgICAgX293bmVkQXNzZXRzW3RvXS5wdXNoKGFzc2V0SWQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBQcml2YXRlIGZ1bmN0aW9uIHRvIGFkZCBhIGFzc2V0IHRvIHRoaXMgZXh0ZW5zaW9uJ3MgYXNzZXQgdHJhY2tpbmcgZGF0YSBzdHJ1Y3R1cmVzLgogICAgICovCiAgICBmdW5jdGlvbiBfYWRkQXNzZXRUb0FsbEFzc2V0c0VudW1lcmF0aW9uKHVpbnQyNTYgYXNzZXRJZCkgcHJpdmF0ZSB7CiAgICAgICAgX2FsbEFzc2V0c0luZGV4W2Fzc2V0SWRdID0gX2FsbEFzc2V0cy5sZW5ndGg7CiAgICAgICAgX2FsbEFzc2V0cy5wdXNoKGFzc2V0SWQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBQcml2YXRlIGZ1bmN0aW9uIHRvIHJlbW92ZSBhIGFzc2V0IGZyb20gdGhpcyBleHRlbnNpb24ncyBvd25lcnNoaXAtdHJhY2tpbmcgZGF0YSBzdHJ1Y3R1cmVzLiBOb3RlIHRoYXQKICAgICAqLwogICAgZnVuY3Rpb24gX3JlbW92ZUFzc2V0RnJvbU93bmVyRW51bWVyYXRpb24oYWRkcmVzcyBmcm9tLCB1aW50MjU2IGFzc2V0SWQpIHByaXZhdGUgewogICAgICAgIC8vIFRvIHByZXZlbnQgYSBnYXAgaW4gZnJvbSdzIGFzc2V0cyBhcnJheSwgd2Ugc3RvcmUgdGhlIGxhc3QgYXNzZXQgaW4gdGhlIGluZGV4IG9mIHRoZSBhc3NldCB0byBkZWxldGUsIGFuZAogICAgICAgIC8vIHRoZW4gZGVsZXRlIHRoZSBsYXN0IHNsb3QgKHN3YXAgYW5kIHBvcCkuCgogICAgICAgIHVpbnQyNTYgbGFzdEFzc2V0SW5kZXggPSBfb3duZWRBc3NldHNbZnJvbV0ubGVuZ3RoLnN1YigxKTsKICAgICAgICB1aW50MjU2IGFzc2V0SW5kZXggPSBfb3duZWRBc3NldHNJbmRleFthc3NldElkXTsKCiAgICAgICAgLy8gV2hlbiB0aGUgYXNzZXQgdG8gZGVsZXRlIGlzIHRoZSBsYXN0IGFzc2V0LCB0aGUgc3dhcCBvcGVyYXRpb24gaXMgdW5uZWNlc3NhcnkKICAgICAgICBpZiAoYXNzZXRJbmRleCAhPSBsYXN0QXNzZXRJbmRleCkgewogICAgICAgICAgICB1aW50MjU2IGxhc3RBc3NldElkID0gX293bmVkQXNzZXRzW2Zyb21dW2xhc3RBc3NldEluZGV4XTsKCiAgICAgICAgICAgIF9vd25lZEFzc2V0c1tmcm9tXVthc3NldEluZGV4XSA9IGxhc3RBc3NldElkOwogICAgICAgICAgICAvLyBNb3ZlIHRoZSBsYXN0IGFzc2V0IHRvIHRoZSBzbG90IG9mIHRoZSB0by1kZWxldGUgYXNzZXQKICAgICAgICAgICAgX293bmVkQXNzZXRzSW5kZXhbbGFzdEFzc2V0SWRdID0gYXNzZXRJbmRleDsKICAgICAgICAgICAgLy8gVXBkYXRlIHRoZSBtb3ZlZCBhc3NldCdzIGluZGV4CiAgICAgICAgfQoKICAgICAgICAvLyBUaGlzIGFsc28gZGVsZXRlcyB0aGUgY29udGVudHMgYXQgdGhlIGxhc3QgcG9zaXRpb24gb2YgdGhlIGFycmF5CiAgICAgICAgX293bmVkQXNzZXRzW2Zyb21dLmxlbmd0aC0tOwoKICAgICAgICAvLyBOb3RlIHRoYXQgX293bmVkQXNzZXRzSW5kZXhbYXNzZXRJZF0gaGFzbid0IGJlZW4gY2xlYXJlZDogaXQgc3RpbGwgcG9pbnRzIHRvIHRoZSBvbGQgc2xvdCAobm93IG9jY3VwaWVkIGJ5CiAgICAgICAgLy8gbGFzdEFzc2V0SWQsIG9yIGp1c3Qgb3ZlciB0aGUgZW5kIG9mIHRoZSBhcnJheSBpZiB0aGUgYXNzZXQgd2FzIHRoZSBsYXN0IG9uZSkuCiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IFByaXZhdGUgZnVuY3Rpb24gdG8gcmVtb3ZlIGEgYXNzZXQgZnJvbSB0aGlzIGV4dGVuc2lvbidzIGFzc2V0IHRyYWNraW5nIGRhdGEgc3RydWN0dXJlcy4KICAgICAqLwogICAgZnVuY3Rpb24gX3JlbW92ZUFzc2V0RnJvbUFsbEFzc2V0c0VudW1lcmF0aW9uKHVpbnQyNTYgYXNzZXRJZCkgcHJpdmF0ZSB7CiAgICAgICAgLy8gVG8gcHJldmVudCBhIGdhcCBpbiB0aGUgYXNzZXRzIGFycmF5LCB3ZSBzdG9yZSB0aGUgbGFzdCBhc3NldCBpbiB0aGUgaW5kZXggb2YgdGhlIGFzc2V0IHRvIGRlbGV0ZSwgYW5kCiAgICAgICAgLy8gdGhlbiBkZWxldGUgdGhlIGxhc3Qgc2xvdCAoc3dhcCBhbmQgcG9wKS4KCiAgICAgICAgdWludDI1NiBsYXN0QXNzZXRJbmRleCA9IF9hbGxBc3NldHMubGVuZ3RoLnN1YigxKTsKICAgICAgICB1aW50MjU2IGFzc2V0SW5kZXggPSBfYWxsQXNzZXRzSW5kZXhbYXNzZXRJZF07CgogICAgICAgIC8vIFdoZW4gdGhlIGFzc2V0IHRvIGRlbGV0ZSBpcyB0aGUgbGFzdCBhc3NldCwgdGhlIHN3YXAgb3BlcmF0aW9uIGlzIHVubmVjZXNzYXJ5LiBIb3dldmVyLCBzaW5jZSB0aGlzIG9jY3VycyBzbwogICAgICAgIC8vIHJhcmVseSAod2hlbiB0aGUgbGFzdCBtaW50ZWQgYXNzZXQgaXMgZGVzdHJveXQpIHRoYXQgd2Ugc3RpbGwgZG8gdGhlIHN3YXAgaGVyZSB0byBhdm9pZCB0aGUgZ2FzIGNvc3Qgb2YgYWRkaW5nCiAgICAgICAgLy8gYW4gJ2lmJyBzdGF0ZW1lbnQgKGxpa2UgaW4gX3JlbW92ZUFzc2V0RnJvbU93bmVyRW51bWVyYXRpb24pCiAgICAgICAgdWludDI1NiBsYXN0QXNzZXRJZCA9IF9hbGxBc3NldHNbbGFzdEFzc2V0SW5kZXhdOwoKICAgICAgICBfYWxsQXNzZXRzW2Fzc2V0SW5kZXhdID0gbGFzdEFzc2V0SWQ7CiAgICAgICAgLy8gTW92ZSB0aGUgbGFzdCBhc3NldCB0byB0aGUgc2xvdCBvZiB0aGUgdG8tZGVsZXRlIGFzc2V0CiAgICAgICAgX2FsbEFzc2V0c0luZGV4W2xhc3RBc3NldElkXSA9IGFzc2V0SW5kZXg7CiAgICAgICAgLy8gVXBkYXRlIHRoZSBtb3ZlZCBhc3NldCdzIGluZGV4CgogICAgICAgIC8vIFRoaXMgYWxzbyBkZWxldGVzIHRoZSBjb250ZW50cyBhdCB0aGUgbGFzdCBwb3NpdGlvbiBvZiB0aGUgYXJyYXkKICAgICAgICBfYWxsQXNzZXRzLmxlbmd0aC0tOwogICAgICAgIF9hbGxBc3NldHNJbmRleFthc3NldElkXSA9IDA7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRvIGRlc3Ryb3kgYSBzcGVjaWZpYyBhc3NldC4KICAgICAqLwogICAgZnVuY3Rpb24gX2Rlc3Ryb3kodWludDI1NiBhc3NldElkLCBieXRlcyBkYXRhKSBpbnRlcm5hbCB7CiAgICAgICAgX2Rlc3Ryb3kob3duZXJPZihhc3NldElkKSwgYXNzZXRJZCwgZGF0YSk7CiAgICB9CgogICAgLyoqCiAgICAgKiBAZGV2IEludGVybmFsIGZ1bmN0aW9uIHRvIHNlbmQgb3duZXJzaGlwIG9mIGEgZ2l2ZW4gYXNzZXQgSUQgdG8gYW5vdGhlciBhZGRyZXNzLgogICAgICovCiAgICBmdW5jdGlvbiBfc2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IGFzc2V0SWQsIGJ5dGVzIGRhdGEpIGludGVybmFsIHsKICAgICAgICByZXF1aXJlKG93bmVyT2YoYXNzZXRJZCkgPT0gZnJvbSwgIkJBQzAwMjogc2VuZCBvZiBhc3NldCB0aGF0IGlzIG5vdCBvd24iKTsKICAgICAgICByZXF1aXJlKHRvICE9IGFkZHJlc3MoMCksICJCQUMwMDI6IHNlbmQgdG8gdGhlIHplcm8gYWRkcmVzcyIpOwoKICAgICAgICBfY2xlYXJBcHByb3ZhbChhc3NldElkKTsKICAgICAgICBfb3duZWRBc3NldHNDb3VudFtmcm9tXS5kZWNyZW1lbnQoKTsKICAgICAgICBfb3duZWRBc3NldHNDb3VudFt0b10uaW5jcmVtZW50KCk7CgogICAgICAgIF9hc3NldE93bmVyW2Fzc2V0SWRdID0gdG87CgogICAgICAgIGVtaXQgU2VuZChtc2cuc2VuZGVyLCBmcm9tLCB0bywgYXNzZXRJZCwgZGF0YSk7CgogICAgICAgIF9yZW1vdmVBc3NldEZyb21Pd25lckVudW1lcmF0aW9uKGZyb20sIGFzc2V0SWQpOwoKICAgICAgICBfYWRkQXNzZXRUb093bmVyRW51bWVyYXRpb24odG8sIGFzc2V0SWQpOwogICAgfQoKICAgIC8qKgogICAgICogQGRldiBJbnRlcm5hbCBmdW5jdGlvbiB0byBpbnZva2UgYG9uQkFDMDAyUmVjZWl2ZWRgIG9uIGEgdGFyZ2V0IGFkZHJlc3MuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9jaGVja09uQkFDMDAyUmVjZWl2ZWQoYWRkcmVzcyBmcm9tLCBhZGRyZXNzIHRvLCB1aW50MjU2IGFzc2V0SWQsIGJ5dGVzIG1lbW9yeSBfZGF0YSkKICAgIGludGVybmFsIHJldHVybnMgKGJvb2wpCiAgICB7CiAgICAgICAgaWYgKCF0by5pc0NvbnRyYWN0KCkpIHsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQoKICAgICAgICBieXRlczQgcmV0dmFsID0gSUJBQzAwMlJlY2VpdmVyKHRvKS5vbkJBQzAwMlJlY2VpdmVkKG1zZy5zZW5kZXIsIGZyb20sIGFzc2V0SWQsIF9kYXRhKTsKICAgICAgICByZXR1cm4gKHJldHZhbCA9PSBfQkFDMDAyX1JFQ0VJVkVEKTsKICAgIH0KCiAgICAvKioKICAgICAqIEBkZXYgUHJpdmF0ZSBmdW5jdGlvbiB0byBjbGVhciBjdXJyZW50IGFwcHJvdmFsIG9mIGEgZ2l2ZW4gYXNzZXQgSUQuCiAgICAgKi8KICAgIGZ1bmN0aW9uIF9jbGVhckFwcHJvdmFsKHVpbnQyNTYgYXNzZXRJZCkgcHJpdmF0ZSB7CiAgICAgICAgaWYgKF9hc3NldEFwcHJvdmFsc1thc3NldElkXSAhPSBhZGRyZXNzKDApKSB7CiAgICAgICAgICAgIF9hc3NldEFwcHJvdmFsc1thc3NldElkXSA9IGFkZHJlc3MoMCk7CiAgICAgICAgfQogICAgfQp9";
    public static final String I_BAC002_SOURCE = "cHJhZ21hIHNvbGlkaXR5IF4wLjQuMjU7Cgpjb250cmFjdCBJQkFDMDAyICB7CiAgICBldmVudCBTZW5kKGFkZHJlc3MgaW5kZXhlZCBmcm9tLCBhZGRyZXNzIGluZGV4ZWQgdG8sIHVpbnQyNTYgYXNzZXRJZCwgYnl0ZXMgZGF0YSk7CiAgICBldmVudCBBcHByb3ZhbCggYWRkcmVzcyBpbmRleGVkIG93bmVyLCBhZGRyZXNzIGFwcHJvdmVkLCB1aW50MjU2IGFzc2V0SWQpOwogICAgZXZlbnQgQXBwcm92YWxGb3JBbGwoIGFkZHJlc3MgaW5kZXhlZCBvd25lciwgYWRkcmVzcyBpbmRleGVkIG9wZXJhdG9yLCBib29sIGFwcHJvdmVkKTsKCiAgICBmdW5jdGlvbiBiYWxhbmNlKGFkZHJlc3Mgb3duZXIpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQyNTYgYmFsYW5jZSk7CgogICAgZnVuY3Rpb24gb3duZXJPZih1aW50MjU2IGFzc2V0SWQpIHB1YmxpYyB2aWV3IHJldHVybnMgKGFkZHJlc3Mgb3duZXIpOwoKICAgIGZ1bmN0aW9uIHNlbmRGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiBhc3NldElkLCBieXRlcyBtZW1vcnkgZGF0YSkgcHVibGljOwoKICAgIGZ1bmN0aW9uIGJhdGNoU2VuZEZyb20oYWRkcmVzcyBmcm9tLCBhZGRyZXNzW10gdG8sIHVpbnQyNTZbXSBhc3NldElkLCBieXRlcyBtZW1vcnkgZGF0YSkgcHVibGljOwoKICAgIGZ1bmN0aW9uIGRlc3Ryb3kodWludDI1NiBhc3NldElkLCBieXRlcyBkYXRhKSBwdWJsaWM7CgogICAgZnVuY3Rpb24gaXNzdWVXaXRoQXNzZXRVUkkoYWRkcmVzcyB0bywgdWludDI1NiBhc3NldElkLCBzdHJpbmcgbWVtb3J5IGFzc2V0VVJJLCBieXRlcyBkYXRhKSBwdWJsaWMgIHJldHVybnMgKGJvb2wpOwoKICAgIGZ1bmN0aW9uIGFzc2V0VVJJKHVpbnQyNTYgYXNzZXRJZCkgZXh0ZXJuYWwgdmlldyByZXR1cm5zIChzdHJpbmcgbWVtb3J5KTsKCiAgICBmdW5jdGlvbiBhcHByb3ZlKGFkZHJlc3MgdG8sIHVpbnQyNTYgYXNzZXRJZCkgcHVibGljOwogICAgZnVuY3Rpb24gZ2V0QXBwcm92ZWQodWludDI1NiBhc3NldElkKSBwdWJsaWMgdmlldyByZXR1cm5zIChhZGRyZXNzIG9wZXJhdG9yKTsKCiAgICBmdW5jdGlvbiBzZXRBcHByb3ZhbEZvckFsbChhZGRyZXNzIHRvLCBib29sIF9hcHByb3ZlZCkgcHVibGljOwogICAgZnVuY3Rpb24gaXNBcHByb3ZlZEZvckFsbChhZGRyZXNzIG93bmVyLCBhZGRyZXNzIG9wZXJhdG9yKSBwdWJsaWMgdmlldyByZXR1cm5zIChib29sKTsKCiAgICBmdW5jdGlvbiBhc3NldE9mT3duZXJCeUluZGV4KGFkZHJlc3Mgb3duZXIsIHVpbnQyNTYgaW5kZXgpIHB1YmxpYyB2aWV3IHJldHVybnMgKHVpbnQyNTYpIDsKCiAgICBmdW5jdGlvbiBzYWZlVHJhbnNmZXJGcm9tKGFkZHJlc3MgZnJvbSwgYWRkcmVzcyB0bywgdWludDI1NiB0b2tlbklkLCBieXRlcyBtZW1vcnkgZGF0YSkgcHVibGljOwp9Cg==";
    public static final String BAC001_MD = "# 积分合约\n" +
            "\n" +
            "## 简介\n" +
            " BAC001 是一套区块链积分合约，具有积分相关的增发，销毁，暂停合约，黑白名单等权限控制等功能。\n" +
            "\n" +
            "## 四个基本元素\n" +
            "\n" +
            "- description \n" +
            "\n" +
            "  此积分的具体描述\n" +
            "\n" +
            "- shortName \n" +
            "\n" +
            "  积分简称\n" +
            "\n" +
            "- minUnit \n" +
            "\n" +
            "  积分最小单位\n" +
            "\n" +
            "- totalAmount \n" +
            "\n" +
            "  积分总数量\n" +
            "\n" +
            "## 五个基本行为: \n" +
            "\n" +
            "- 发行\n" +
            "\n" +
            "  调用合约的 deploy 方法，传入你初始化的四个元素即可，即在区块链上发行了你指定总量和名称的积分。\n" +
            "\n" +
            "  - 其中 minUnit 和 totalAmount 不能为负数或小数\n" +
            "\n" +
            "- 转账\n" +
            "\n" +
            "  调用 send 方法即可实现转账，之后调用 balance 方法可以查看自己的积分余额\n" +
            "\n" +
            "- 增发\n" +
            "\n" +
            "  调用 issue 方法特定地址增发积分， 并可以通过 addIssuer 增加有权限增发积分的人，也可以通过renounceIssuer 方法移除增发权限\n" +
            "\n" +
            "- 销毁\n" +
            "\n" +
            "  调用 destroy 以及 destroyFrom 销毁自己地址下积分和特定地址下的积分\n" +
            "\n" +
            "- 暂停\n" +
            "\n" +
            "  遇到紧急状况，你可以调用 suspend 方法，暂停合约，这样任何人都不能调用 send 函数。故障修复后，可以调用 unSuspend 方法解除暂停。也可以通过 addSuspender 和 renounceSuspender 相应增加和移除暂停者权限\n" +
            "\n" +
            "\n" +
            "## 接口说明\n" +
            "\n" +
            "- <b>totalAmount()</b>\n" +
            "\n" +
            "  返回积分总量\n" +
            "\n" +
            "  - 这里的积分总量需要计算最小转账单位，所以实际返回值为   totalAmount * 10<sup>minUnit</sup> \n" +
            "\n" +
            "- <b>balance(address owner)</b>\n" +
            "\n" +
            "  返回owner的帐户的积分余额\n" +
            "\n" +
            "- <b>send(address to, uint256 value , string data)</b>\n" +
            "\n" +
            "  将数量为value的积分转入地址 to 并触发 transfer 事件, data 是转账备注\n" +
            "\n" +
            "  - suspend 状态下无法进行此操作\n" +
            "  - 请避免 to 为自身进行操作\n" +
            "\n" +
            "- <b>sendFrom(address from,address to,uint256 value，string  data))</b>\n" +
            "\n" +
            "  将地址 from 中的 value 数量的积分转入地址 to ，并触发 transfer 事件，data 是转账备注。\n" +
            "\n" +
            "  - 方法的调用者可以不为 from， 此时需要预先进行 approve 授权\n" +
            "\n" +
            "  - from 不能为调用者自身地址，否则会报错\n" +
            "  - suspend 状态下无法执行此操作\n" +
            "\n" +
            "- <b>safeSendFrom(address from, address to, uint256 value,  string data)</b>\n" +
            "\n" +
            "  安全的将地址 from 中的 value 数量的积分转入地址 to ( to如果是合约地址，必须实现接收接口 BAC001Holder 才可以接收转账) ，并触发 transfer 事件，data 是转账备注\n" +
            "\n" +
            "  - suspend 状态下无法执行此操作\n" +
            "\n" +
            "- <b>safeBatchSend( address[] to, uint256[]  values, string  data)</b>\n" +
            "\n" +
            "  批量将自己账户下的积分转给 to 数组的地址， to 和 values 的个数要一致\n" +
            "\n" +
            "  - suspend 状态下无法执行此操作\n" +
            "\n" +
            "- <b>approve(address spender,uint256 value)</b>\n" +
            "\n" +
            "  允许 spender 从自己账户提取限额 value 的积分\n" +
            "\n" +
            "  - 此方法配合 sendfrom / safesendfrom 一起使用\n" +
            "  - 重复授权时，最终授权额度为最后一次授权的值\n" +
            "\n" +
            "- <b>allowance(address owner,address spender)</b>\n" +
            "\n" +
            "  返回 spender 可从 owner 提取的积分数量上限\n" +
            "\n" +
            "  - 此方法配合 approve 一起使用\n" +
            "\n" +
            "- <b>increaseAllowance(address spender, uint256 addedValue)</b>\n" +
            "\n" +
            "  允许 spender 提取的积分上限在原有基础上增加 addedValue\n" +
            "\n" +
            "  - 此方法配合 approve 使用\n" +
            "\n" +
            "- <b>decreaseAllowance(address spender, uint256 subtractedValue)</b>\n" +
            "\n" +
            "  允许 spender  提取的积分上限在原有基础上减少 subtractedValue\n" +
            "\n" +
            "  - 此方法配合 approve 使用\n" +
            "\n" +
            "- <b>minUnit()</b>\n" +
            "\n" +
            "  积分最小单位\n" +
            "\n" +
            "- <b>shortName()</b>\n" +
            "\n" +
            "  积分简称\n" +
            "\n" +
            "- <b>description()</b>\n" +
            "\n" +
            "  积分描述\n" +
            "\n" +
            "- <b>destroy(uint256 value， string  data)</b>\n" +
            "\n" +
            "  减少自己的积分，data 是转账备注\n" +
            "\n" +
            "  - 调用时，value 值需要小于等于目前自己的积分总量\n" +
            "\n" +
            "- <b>destroyFrom(address from, uint256 value， string  data)</b>\n" +
            "\n" +
            "  减少地址 from 积分，data 是转账备注\n" +
            "\n" +
            "  - 调用此方法时，需要配合 approve 进行使用\n" +
            "\n" +
            "- <b>issue(address to, uint256 value，string  data)</b>\n" +
            "\n" +
            "  给地址 to 增加数量为 value 的积分，data 是转账备注\n" +
            "\n" +
            "- <b>isIssuer(address account)</b>\n" +
            "\n" +
            "  检查 account 是否有增加积分的权限\n" +
            "\n" +
            "- <b>addIssuer(address account)</b>\n" +
            "\n" +
            "  使地址 account 拥有增加积分的权限\n" +
            "\n" +
            "- <b>renounceIssuer()</b>\n" +
            "\n" +
            "  移除增加积分的权限\n" +
            "\n" +
            "- <b>suspend()</b>\n" +
            "\n" +
            "  暂停合约\n" +
            "\n" +
            "  - suspend 后无法进行 send / safesendfrom / sendfrom / safeBatchSend / approves 操作\n" +
            "\n" +
            "- <b>unSuspend()</b>\n" +
            "\n" +
            "  重启合约\n" +
            "  \n" +
            "- <b>suspended</b>\n" +
            "\n" +
            "  判断合约是否处于暂停状态\n" +
            "\n" +
            "- <b>isSuspender(address account)</b>\n" +
            "\n" +
            "  是否有暂停合约权限\n" +
            "\n" +
            "  - 配合 suspend 方法一起使用\n" +
            "\n" +
            "- <b>addSuspender(address account)</b>\n" +
            "\n" +
            "  增加暂停权限者\n" +
            "\n" +
            "  - 配合 suspend 方法一起使用\n" +
            "\n" +
            "- <b>renounceSuspender()</b>\n" +
            "\n" +
            "  移除暂停权限\n" +
            "\n" +
            "  - 配合 suspend / addSuspender 方法使用\n" +
            "\n" +
            "\n";
    public static final String BAC002_MD = "# BAC002 合约规范\n"
        + "\n"
        + "## 简介\n"
        + " BAC002 是区块链上定义非同质化资产的一种标准，可以用于唯一性资产类型，如房产、汽车、道具、版权等。，并可以做相应增发，销毁，暂停合约，黑白名单等权限控制。\n"
        + "## 三个基本元素\n"
        + "- description\n"
        + "\n"
        + "  资产的具体描述\n"
        + "\n"
        + "- shortName\n"
        + "\n"
        + "  资产简称\n"
        + "\n"
        + "- assetId\n"
        + "\n"
        + "  资产编号\n"
        + "\n"
        + " ## 五个基本行为\n"
        + "- 发行\n"
        + "\n"
        + "  调用合约的 deploy 方法，传入 description 和 shortName，即在区块链上发行指定名称的资产\n"
        + "\n"
        + "- 转账\n"
        + "\n"
        + "  调用 safeSendFrom 方法实现转账，调用 balance 方法可以查看自己的资产数量\n"
        + "\n"
        + "- 增发\n"
        + "\n"
        + "  调用 issueWithAssetURI 方法向资产地址增发指定资产编号和资产描述链接信息的资产。另外，可以通过 addIssuer 增加 有权限增发资产的人，也可以通过 renounceIssuer 方法移除增发权限\n"
        + "\n"
        + "- 销毁\n"
        + "\n"
        + "  调用 destroy 以及 destroyFrom 销毁自己地址下资产和特定地址下的资产\n"
        + "\n"
        + "- 暂停\n"
        + "\n"
        + "  遇到紧急状况，你可以调用 suspend 方法，暂停合约，这样任何人都不能调用 send 函数。故障修复后，可以调用 unSuspend 方法解除暂停。也可以通过 addSuspender 和 renounceSuspender 相应增加和移除暂停者权限\n"
        + "\n"
        + "\n"
        + "## 接口说明\n"
        + "\n"
        + "- <b>shortName()</b>\n"
        + "\n"
        + "  资产简称\n"
        + "\n"
        + "- <b>description()</b>\n"
        + "\n"
        + "  资产描述\n"
        + "\n"
        + "- <b>balance(address owner)</b>\n"
        + "\n"
        + "  返回 owner 的资产总数\n"
        + "\n"
        + "- <b>totalSupply()</b>\n"
        + "\n"
        + "  获得当前合约总的资产数目\n"
        + "\n"
        + "- <b>ownerOf(uint256 assetId)</b>\n"
        + "\n"
        + "  返回资产持有者的地址\n"
        + "\n"
        + "- <b>approve(address to, uint256 assetId)</b>\n"
        + "\n"
        + "  授予地址to具有指定资产的控制权\n"
        + "\n"
        + "  - 此方法配合 getapproved 使用\n"
        + "\n"
        + "- <b>getApproved(uint256 assetId)</b>\n"
        + "\n"
        + "  获得资产授权的地址用户\n"
        + "\n"
        + "  - 此方法配合 approve 使用，注意不要配合 setapprovealforall 方法使用\n"
        + "\n"
        + "- <b>setApprovalForAll(address operator, bool approved)</b>\n"
        + "\n"
        + "  授予地址operator具有自己所有资产的控制权\n"
        + "\n"
        + "- <b>isApprovedForAll(address owner, address operator)</b>\n"
        + "\n"
        + "  查询授权\n"
        + "\n"
        + "- <b>sendFrom(address from, address to, uint256 assetId, bytes memory data)</b>\n"
        + "\n"
        + "  安全转账，防止你转到错误的合约地址 ( to如果是合约地址，必须实现接收接口 BAC002Holder 才可以接收转账 )，并可以带转账备注\n"
        + "\n"
        + "  - suspend 状态下无法执行此操作\n"
        + "\n"
        + "- <b>batchSendFrom(address from, address[] to, uint256[] assetId, bytes memory data)</b>\n"
        + "\n"
        + "  批量安全转账\n"
        + "\n"
        + "  - suspend 状态下无法执行此操作\n"
        + "  - to 数组元素个数需要和 assetid 数组元素个数一致\n"
        + "\n"
        + "- <b>issueWithAssetURI(address to, uint256 assetId, string memory assetURI, bytes data)</b>\n"
        + "\n"
        + "  给地址 to 创建资产 assetId，data 是转账备注, assetURI  资产描述\n"
        + "\n"
        + "- <b>isIssuer(address account)</b>\n"
        + "\n"
        + "  检查account是否有增加资产的权限\n"
        + "\n"
        + "- <b>addIssuer(address account)</b>\n"
        + "\n"
        + "  使地址 account 拥有增加资产的权限\n"
        + "\n"
        + "- <b>renounceIssuer()</b>\n"
        + "\n"
        + "  移除增加资产的权限\n"
        + "\n"
        + "- <b>suspend()</b>\n"
        + "\n"
        + "  暂停合约\n"
        + "\n"
        + "  - suspend 后无法进行 safesendfrom / sendfrom / safeBatchSendFrom 操作\n"
        + "\n"
        + "- <b>unSuspend()</b>\n"
        + "\n"
        + "  重启合约\n"
        + "\n"
        + "  - 此方法配合 suspend 使用\n"
        + "\n"
        + "- <b>isSuspender(address account)</b>\n"
        + "\n"
        + "  是否有暂停合约权限\n"
        + "\n"
        + "  - 此方法配合  addsuspender 使用\n"
        + "\n"
        + "- <b>addSuspender(address account)</b>\n"
        + "\n"
        + "  增加暂停权限者\n"
        + "\n"
        + "  - 此方法配合 renouncesuspender / issuspender 放啊发使用\n"
        + "\n"
        + "- <b>renounceSuspender()</b>\n"
        + "\n"
        + "  移除暂停权限\n"
        + "\n"
        + "- <b>destroy(uint256 assetId, bytes data)</b>\n"
        + "\n"
        + "  减少自己的资产，data 是转账备注\n"
        + "\n"
        + "  - 调用时，value 值需要小于等于目前自己的资产总量\n"
        + "\n"
        + "- <b>assetOfOwnerByIndex(address owner, uint256 index)</b>\n"
        + "\n"
        + "  根据索引 index 获取 owner 的资产 ID\n"
        + "\n"
        + "- <b>assetByIndex(uint256 index)</b>\n"
        + "\n"
        + "  根据索引  index 获取当前合约的资产 ID\n"
        + "\n";
}
